package cn.swanit.common.base.util;

import cn.hutool.crypto.SecureUtil;
import cn.swanit.common.base.enums.IotCloudEnum;
import cn.swanit.common.base.exception.IotCloudException;
import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameters;
import java.util.Arrays;


public class AesUtil {

    private AesUtil() {
    }

    private static final String AES_KEY = "vFxMUxH15WnsUkaz";

    private static final cn.hutool.crypto.symmetric.AES AES = SecureUtil.aes(AES_KEY.getBytes());

    public static String decryptStr(String data) {
        try {
            return AES.decryptStr(data);
        } catch (Exception e) {
            throw new IotCloudException(IotCloudEnum.SYS_2000002);
        }
    }

    public static String encryptBase64Str(String data) {
        return AES.encryptBase64(data);
    }

    public static String encryptHexStr(String data) {
        return AES.encryptHex(data);
    }

    public static String decryptMiniApp(String sessionKey, String encryptedData, String ivStr) {
        try {
            AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
            params.init(new IvParameterSpec(Base64.decodeBase64(ivStr)));
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(Base64.decodeBase64(sessionKey), "AES"), params);
            return new String(PKCS7Encoder.decode(cipher.doFinal(Base64.decodeBase64(encryptedData))), StandardCharsets.UTF_8);
        } catch (Exception var5) {
            throw new IotCloudException(IotCloudEnum.SYS_2000002);
        }
    }

    public static class PKCS7Encoder {
        private static final Charset CHARSET = StandardCharsets.UTF_8;

        private PKCS7Encoder() {
        }

        public static byte[] encode(int count) {
            int amountToPad = 32 - count % 32;
            char padChr = chr(amountToPad);
            StringBuilder tmp = new StringBuilder();

            for (int index = 0; index < amountToPad; ++index) {
                tmp.append(padChr);
            }

            return tmp.toString().getBytes(CHARSET);
        }

        public static byte[] decode(byte[] decrypted) {
            int pad = decrypted[decrypted.length - 1];
            if (pad < 1 || pad > 32) {
                pad = 0;
            }
            return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
        }

        private static char chr(int a) {
            byte target = (byte) (a & 255);
            return (char) target;
        }
    }
}
